package com.liveneo.adapter.mobile.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Maps;
import com.liveneo.adapter.base.entity.PrpmMobilePushCid;
import com.liveneo.adapter.base.entity.PrpmSurveyUser;
import com.liveneo.adapter.base.entity.PrpmUserOnline;
import com.liveneo.adapter.base.entity.PrpmUserRegister;
import com.liveneo.adapter.base.mapper.PrpmMobilePushCidMapper;
import com.liveneo.adapter.base.mapper.PrpmSurveyUserMapper;
import com.liveneo.adapter.base.mapper.PrpmUserOnlineMapper;
import com.liveneo.adapter.base.mapper.PrpmUserRegisterMapper;
import com.liveneo.adapter.base.support.BaseServiceImpl;
import com.liveneo.adapter.base.support.LogUtils;
import com.liveneo.adapter.mobile.model.BaseResponse;
import com.liveneo.adapter.mobile.model.request.LoginRequest;
import com.liveneo.adapter.mobile.model.request.RegisterUserRequest;
import com.liveneo.adapter.mobile.model.response.LoginResponse;
import com.liveneo.adapter.mobile.service.MobileAuthService;
import com.liveneo.adapter.mobile.service.ValidateService;
import com.liveneo.adapter.mobile.support.MobileReturnCodeSupport;
import com.liveneo.adapter.mobile.util.UUIDUtils;
import com.liveneo.system.base.utils.AppException;

/**
 * 用户业务处理
 * 
 * @author wangxx
 *
 */
@Service
@Transactional
public class MobileAuthServiceImpl extends BaseServiceImpl implements MobileAuthService {
//    @Autowired
//    private SurveyUserDao surveyUserDao;
//    @Autowired
//    private UserOnlineDao userOnlineDao;
//    @Autowired
//    private MobilePushCidDao mobilePushCidDao;
//    @Autowired
//    private UserRegisterDao userRegisterDao;
    @Autowired
    PrpmSurveyUserMapper prpmSurveyUserMapper;
    @Autowired
    PrpmUserOnlineMapper prpmUserOnlineMapper;
    @Autowired
    PrpmMobilePushCidMapper prpmMobilePushCidMapper;
    @Autowired
    PrpmUserRegisterMapper prpmUserRegisterMapper;
    @Autowired
    private ValidateService validateService;

    /**
     * 用户的登陆操作：
     * 执行步骤：校验-->用户认证-->执行用户登陆-->维护手机个推关系表
     */
    @Override
    public LoginResponse login(LoginRequest request) throws ParseException {
        // 校验登陆的参数
        LogUtils.info("开始校验登陆参数");
        Map<String, Object> result = validateService.validateLogin(request);
        Integer resultCode = (Integer) result.get("result");
        if (resultCode == 2) {
            LogUtils.info("校验登陆参数失败，返回错误信息");
            // 失败返回错误信息
            return MobileReturnCodeSupport.buildReponse((String) result.get("code"),MobileReturnCodeSupport.SYS_CODE, (String) result.get("detailCode"),
                    LoginResponse.class);
        }
        // 用户认证
        LogUtils.info("开始认证用户");
        String userCode = request.getUserCode();
        PrpmSurveyUser user = prpmSurveyUserMapper.findByUserCode(userCode);
        result = userAuth(user, request.getFromPlat(), request.getPassword());
        resultCode = (Integer) result.get("result");
        if (resultCode == 2) {
            LogUtils.info("认证用户失败，返回错误信息");
            return MobileReturnCodeSupport.buildReponse((String) result.get("code"),MobileReturnCodeSupport.SYS_CODE, (String) result.get("detailCode"),
                    LoginResponse.class);
        }
        // 执行登陆操作
        LogUtils.info("开始执行登陆操作");
        result = doLogin(user, request.getDeviceUuid());
        resultCode = (Integer) result.get("result");
        if (resultCode == 2) {
            LogUtils.info("登陆失败，返回错误信息");
            return MobileReturnCodeSupport.buildReponse((String) result.get("code"),MobileReturnCodeSupport.SYS_CODE, (String) result.get("detailCode"),
                    LoginResponse.class);
        }
        // 维护用户个推关系表
        LogUtils.info("开始保存个推用户表");
        String clientId = request.getCid();
        String phoneType = request.getPhoneType();
        if (phoneType == null) {
            phoneType = request.getOs();
        }
        if (clientId != null && !"".equals(clientId)) {
            LogUtils.info("clientId不为空，保存个推信息");
            saveOrUpdateMobilePushCid(clientId, user.getMobile(), phoneType, user.getSurveyName(), "1", null);
        }
        // 返回用户信息
        LogUtils.info("开始转化返回信息");
        LoginResponse response = MobileReturnCodeSupport.buildReponse(MobileReturnCodeSupport.CODE_SUCCESS,MobileReturnCodeSupport.SYS_CODE, null,
                LoginResponse.class);
        response.setMobile(user.getMobile());
        response.setOrgCode(user.getOrgCode());
        response.setOrgUuid(user.getOrgId());
        response.setUserName(user.getSurveyName());
        // response.setSurveyName(user.getSurveyName());
        response.setSurveyUserCode(user.getSurveyUserCode());
        response.setUserCode(user.getSurveyUserCode());
        // response.setSurveyUserType(user.getSurveyUserType());
        return response;
    }

    /**
     * 用户认证
     * 
     * @param user 用户信息
     * @param fromPlat 访问的来源 1.创盈平台 密码不需要校验
     * @param password 请求的密码
     * @return 返回结果 result:1认证成功 2认证失败; code:失败的错误代码 ;detailCode :详细错误代码
     */
    private Map<String, Object> userAuth(PrpmSurveyUser user, String fromPlat, String password) {
        Map<String, Object> result = Maps.newHashMap();
        if (user == null) {
            // 登录名未找到对应的用户
            LogUtils.error("手机端登陆时 登录名未找到对应的用户！");
            result.put("result", 2);
            result.put("code", MobileReturnCodeSupport.CODE_ERR_AUTH);
            result.put("detailCode", MobileReturnCodeSupport.CODE_ERROR_AUTH_USERCODE_NOTEXISTS);
        } else {
            String pwd = user.getPassword();
//            if (!"1".equals(fromPlat) && !UserUtil.validatePassword(password.toLowerCase(), pwd)) {
//                // 非创盈平台 密码不正确
//                LogUtils.error("手机端登陆时 登录名跟密码不匹配！");
//                result.put("result", 2);
//                result.put("code", MobileReturnCodeSupport.CODE_ERR_AUTH);
//                result.put("detailCode", MobileReturnCodeSupport.CODE_ERROR_AUTH_PASSWORDERROR);
//            } else {
//                result.put("result", 1);
//            }
        }
        return result;
    }

    /**
     * 执行登陆操作
     * 
     * @param user 用户
     * @param deviceUuid 终端设备号
     * @return 返回结果 result:1登陆成功 2登陆失败; code:失败的错误代码 ;detailCode :详细错误代码
     * @throws ParseException 日期转换异常
     */
    private Map<String, Object> doLogin(PrpmSurveyUser user, String deviceUuid) throws ParseException {
        Map<String, Object> result = Maps.newHashMap();
        PrpmUserOnline online = prpmUserOnlineMapper.selectByUserCode(user.getSurveyUserCode());
        if (online != null) {
            LogUtils.info("用户在线表不为空，查看表中数据的登陆时间");
            // 该用户已经存在online表中，判断距离上次在线时间差，为了精确 获取的服务器时间
            String current = prpmUserOnlineMapper.getCurrentTime();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date now = sdf.parse(current);
//            if (deviceUuid != null && !deviceUuid.equals(online.getDeviceUuid())) {
//                // 查看上个登陆设备到现在的时间差，检查是否在线.这里的时间比较切记要用数据库的时间，不能用当前服务器的时间
//                int timeDiff = (int) ((now.getTime() - online.getOnlineTime().getTime()) / 1000);
//                if (timeDiff < 20) {
//                    LogUtils.warn("手机端登陆时 当前用户已经在线！");
//                    result.put("result", 2);
//                    result.put("code", MobileReturnCodeSupport.CODE_NOVALID_PARAM);
//                    result.put("detailCode", MobileReturnCodeSupport.CODE_PARAM_NO_PHONENO);
//                    return result;
//                } else {
//                    LogUtils.info("距离上次登陆时间已经超20秒，执行更新登录表操作");
//                }
//            }
            online.setOnlineTime(now);
//            online.setDeviceUuid(deviceUuid);
            prpmUserOnlineMapper.updateByPrimaryKey(online);
        } else {
            // 该用户不存在online表中，在表中添加
            LogUtils.info("将用户添加到用户在线表中");
            online = new PrpmUserOnline();
            online.setUserCode(user.getSurveyUserCode());
//            online.setDeviceUuid(deviceUuid);
            online.setLoginName(user.getMobile());
            prpmUserOnlineMapper.insert(online);
        }
        result.put("result", 1);
        return result;
    }

    /**
     * 维护用户个推关系表
     * 
     * @param imei 个推返回的CID
     * @param phoneNo 手机号码
     * @param phoneType 终端类型：1.ios，2.Android
     * @param userName 用户名称
     * @param flag 标识符 1.移动查勘 2.自助查勘
     * @param deviceToken ios APNS推送标识
     */
    private void saveOrUpdateMobilePushCid(String imei, String phoneNo, String phoneType, String userName, String flag,
            String deviceToken) {
        // 维护cid与用户关系表
        List<PrpmMobilePushCid> mobileCids = prpmMobilePushCidMapper.selectByClientId(imei);
        if (mobileCids != null && mobileCids.size() > 0) {
            LogUtils.info("更新个推关系");
            for (PrpmMobilePushCid mobileCid : mobileCids) {
                mobileCid.setMobile(phoneNo);
//                mobileCid.setAppType(Integer.parseInt(phoneType));
                mobileCid.setFlag(flag);
                if (userName != null) {
                    mobileCid.setUpdateBy(userName);
                }
                mobileCid.setUpdateTime(new Date());
                if (deviceToken != null) {
                    mobileCid.setDeviceToken(deviceToken);
                }
                prpmMobilePushCidMapper.updateByPrimaryKey(mobileCid);
            }
        } else {
            LogUtils.info("新增个推关系");
            PrpmMobilePushCid mobileCid = new PrpmMobilePushCid();
            mobileCid.setClientId(imei);
            mobileCid.setMobile(phoneNo);
//            mobileCid.setAppType(Integer.parseInt(phoneType));
            mobileCid.setFlag(flag);
            if (userName != null) {
                mobileCid.setCreateBy(userName);
            }
            mobileCid.setCreateTime(new Date());
            if (deviceToken != null) {
                mobileCid.setDeviceToken(deviceToken);
            }
            prpmMobilePushCidMapper.insert(mobileCid);
        }
    }

    /**
     * 更新密码
     * 三个参数都为必填，密码都由客户端MD5加密
     */
    @Override
    public BaseResponse updatePassword(String surveyUserCode, String oldPassword, String newPassword) {
        if (surveyUserCode == null || "".equals(surveyUserCode) || oldPassword == null || "".equals(oldPassword)
                || newPassword == null || "".equals(newPassword)) {
            // 参数中有为空的，返回参数解析错误
            LogUtils.error("参数不能为空， 返回错误信息");
            return MobileReturnCodeSupport.buildBaseReponse(MobileReturnCodeSupport.CODE_ERR_PARAM,
                    MobileReturnCodeSupport.SYS_CODE, MobileReturnCodeSupport.CODE_ERR_PARAM_NO_EXISTS);
        }
        PrpmSurveyUser user = prpmSurveyUserMapper.findByUserCode(surveyUserCode);
        if (user == null) {
            // 该手机号未找到用户 返回参数错误
            LogUtils.error("手机号未找到用户，返回错误信息");
            return MobileReturnCodeSupport.buildBaseReponse(MobileReturnCodeSupport.CODE_ERR_AUTH,
                    MobileReturnCodeSupport.SYS_CODE, MobileReturnCodeSupport.CODE_ERROR_AUTH_USERCODE_NOTEXISTS);
        } else if (oldPassword.toLowerCase().equals(user.getPassword())) {// 用户传入的MD5加密的密码和数据库中存储的MD5加密的密码
            // 该手的旧密码与数据库中不匹配
            LogUtils.error("旧密码不匹配，返回错误信息");
            return MobileReturnCodeSupport.buildBaseReponse(MobileReturnCodeSupport.CODE_ERR_AUTH,
                    MobileReturnCodeSupport.SYS_CODE, MobileReturnCodeSupport.CODE_ERROR_AUTH_PASSWORDERROR);
        } else {
            // 更新密码
            LogUtils.info("执行更新密码操作");
            // user.setPassword(UserUtil.enctypePassword(newPassword.toLowerCase()));
            user.setPassword(newPassword.toLowerCase());
            prpmSurveyUserMapper.updateByPrimaryKey(user);
            return MobileReturnCodeSupport.buildBaseReponse(MobileReturnCodeSupport.CODE_SUCCESS,
                    MobileReturnCodeSupport.SYS_CODE, null);
        }
    }

    @Override
    public void registerSuccess(RegisterUserRequest request) {
        LogUtils.info("手机注册开始");
        PrpmUserRegister register = prpmUserRegisterMapper.selectByPhoneNo(request.getPhoneNo());
        if (register != null) {
            // 注册用户的手机号已经被注册
            prpmUserRegisterMapper.deleteByPhoneNo(request.getPhoneNo());
        }
        register = new PrpmUserRegister();
        register.setUserRegisterId(UUIDUtils.getUUIDStr());
        register.setMobile(request.getPhoneNo());
        register.setCreateTime(new Date());
        register.setRegisterTime(new Date());
        register.setImei(request.getImei());
        Integer mobileplat = Integer.parseInt(request.getOs());
        register.setMobilePlat(mobileplat);
        register.setValidStatus("1");
        prpmUserRegisterMapper.insert(register);
//        String imei = register.getImei();
//        // 维护cid与用户关系表
//        if (imei != null && !"".equals(imei)) {
//            LogUtils.info("imei不为空，保存个推信息");
//            saveOrUpdateMobilePushCid(imei, request.getPhoneNo(), request.getOs(), null, "2",
//                    request.getDeviceToken());
//        }
    }

    @Override
    public void cancleSuccess(RegisterUserRequest request) {
        LogUtils.info("手机解绑开始");
        prpmUserRegisterMapper.deleteByPhoneNo(request.getPhoneNo());
        // TODO 插入prpmRegisterHis表
        // 维护PrpmMobileCID表
//        String imei = request.getImei();
//        if (imei != null && !"".equals(imei)) {
//            prpmMobilePushCidMapper.deleteByClientIdAndMobile(imei, request.getPhoneNo());
//        } else {
//            prpmMobilePushCidMapper.deleteByPhoneNo(request.getPhoneNo());
//        }
    }

    @Override
    public void logout(String surveyUserCode) throws AppException {
        PrpmSurveyUser user = prpmSurveyUserMapper.findByUserCode(surveyUserCode);
        if (user != null) {
            String mobilePhone = user.getMobile();
            prpmMobilePushCidMapper.deleteByPhoneNo(mobilePhone);
        } else {
            // 补全校验信息
            LogUtils.error("用户代码未找到用户");
            throw new AppException(MobileReturnCodeSupport.CODE_ERR_AUTH,
                    MobileReturnCodeSupport.CODE_ERROR_AUTH_USERCODE_NOTEXISTS);
        }
    }

    @Override
    public void userOnline(String surveyUserCode) throws AppException {
        PrpmUserOnline online = prpmUserOnlineMapper.selectByUserCode(surveyUserCode);
        if (online != null) {
            online.setOnlineTime(new Date());
            prpmUserOnlineMapper.updateByPrimaryKey(online);
        } else {
            LogUtils.error("用户代码未找到用户");
            throw new AppException(MobileReturnCodeSupport.CODE_ERR_AUTH,
                    MobileReturnCodeSupport.CODE_ERROR_AUTH_USERCODE_NOTEXISTS);
        }
    }
}
